package com.scs.application.modules.fsd.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.PinYinUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.core.utils.WebUtils;
import com.scs.application.modules.fsd.consts.FsdConst;
import com.scs.application.modules.fsd.dto.SaveStockDTO;
import com.scs.application.modules.fsd.entity.*;
import com.scs.application.modules.fsd.mapper.IntelliAPIMapper;
import com.scs.application.modules.fsd.service.*;
import com.scs.application.modules.fsd.vo.*;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.security.UserPrincipal;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.TaskExecutor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 */
@Service
public class IntelliAPIServiceImpl implements IntelliAPIService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private FsdRoleService fsdRoleService;
    @Autowired
    private FsdUserService fsdUserService;
    @Autowired
    private IntelliAPIMapper intelliAPIMapper;
    @Autowired
    private FsdStockService fsdStockService;
    @Autowired
    private SPDService spdService;
    @Autowired
    private StationService stationService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private FpTempletsService fsdFpTempletsService;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Qualifier("fsdTask")
    @Autowired
    private TaskExecutor fsdtaskExecutor;


    @Override
    public LoginResult getUserInfoByToken(String token) {
        UserPrincipal currentUser = UserUtils.currentUser();
        FsdUser fsdUser = fsdUserService.getById(currentUser.getId());
        List<Map<String, Object>> roles = new ArrayList<>();
        Map<String, Object> mouldStructure = new HashMap<>();
        //加入角色
        List<FsdRole> fsdRoles = fsdRoleService.listRoleByUserId(currentUser.getId());
        for (FsdRole role : fsdRoles) {
            Map<String, Object> ro = new HashMap<>();
            if (role.getRoleKey().equals("setting")) {
                ro.put("mouldName", "100");
                ro.put("iconLogo", FsdConst.iconCog);
            } else if (role.getRoleKey().equalsIgnoreCase("Operation_Preparation")) {
                ro.put("mouldName", "2");//需要在后台管理中添加这些配置
                ro.put("iconLogo", FsdConst.iconNotesMedical);
            } else if (role.getRoleKey().equalsIgnoreCase("OperatingRoom_Preparation")) {
                ro.put("mouldName", "2");
                ro.put("iconLogo", FsdConst.iconPrescriptionBottleAlt);
            } else if (role.getRoleKey().equalsIgnoreCase("stock")) {
                ro.put("mouldName", "3");
                ro.put("iconLogo", FsdConst.iconClipboardList);
            } else if (role.getRoleKey().equalsIgnoreCase("Report")) {
                ro.put("mouldName", "4");
                ro.put("iconLogo", FsdConst.iconFileSignature);
            } else if (role.getRoleKey().equalsIgnoreCase("DVR")) {
                ro.put("mouldName", "5");
                ro.put("iconLogo", FsdConst.iconFileVideo);
            } else if (role.getRoleKey().equalsIgnoreCase("Low_Consume")) {
                ro.put("mouldName", "1");
                ro.put("iconLogo", FsdConst.iconCoins);
            } else if (role.getRoleKey().equalsIgnoreCase("Operation_Return")) {
                ro.put("mouldName", "1");
                ro.put("iconLogo", FsdConst.iconDollyflatbed);
            } else if (role.getRoleKey().equalsIgnoreCase("Transfer")) {
                ro.put("mouldName", "1");
                ro.put("iconLogo", FsdConst.iconTruckLoading);
            } else if (role.getRoleKey().equalsIgnoreCase("Replenishment")) {
                ro.put("mouldName", "1");
                ro.put("iconLogo", FsdConst.iconBoxes);
            } else if (role.getRoleKey().equalsIgnoreCase("OutboundOrder")) {
                ro.put("mouldName", "OutboundOrder");
                ro.put("iconLogo", FsdConst.iconBoxes);
            } else if (role.getRoleKey().equalsIgnoreCase("Delivery")) {
                ro.put("mouldName", "Delivery");
                ro.put("iconLogo", FsdConst.iconTruckLoading);
            } else {
                ro.put("mouldName", "1");
                ro.put("iconLogo", FsdConst.iconBoxes);
            }
            ro.put("id", role.getId());
            ro.put("iconName", role.getRoleName());
            ro.put("business", role.getRoleKey());
            roles.add(ro);
        }
        for (FsdRole role : fsdRoles) {
            mouldStructure.put(role.getRoleKey(), getMouldOne(role.getRoleKey()));
        }
        List<Map<String, Object>> sheetShortcut = new ArrayList<>();
        for (int i = 1; i < 5; i++) {
            Map<String, Object> shortcutItem = new HashMap<>();
            Map sheet = new HashMap();
            sheet.put("tab", "sheet" + i);
            sheet.put("title", i == 1 ? "库存统计" : i == 2 ? "近效期统计" : i == 3 ? "取出数量" : "消耗数量");
            shortcutItem.put("sheet", sheet);
            List<Map<String, String>> subSheet = new ArrayList<>();
            for (int j = 1; j < 4; j++) {
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.DATE, -j + 1);
                Map sub = new HashMap();
                sub.put("tab", "subSheet" + j);
                sub.put("title", i == 1 && j == 1 ? "盘亏" : i == 1 && j == 2 ? "盘盈" : i == 1 && j == 3 ? "库存" : i == 2 && j == 1 ? "过效期" : i == 2 && j == 2 ? "近30天" : i == 2 && j == 3 ? "近60天" : i == 3 && j == 1 ? DateUtils.format(new Date(), "dd") + "号取出" : i == 3 && j == 2 ? DateUtils.format(cal.getTime(), "dd") + "号取出" : i == 3 && j == 3 ? DateUtils.format(cal.getTime(), "dd") + "号取出" : i == 4 && j == 1 ? DateUtils.format(new Date(), "dd") + "号消耗" : i == 4 && j == 2 ? DateUtils.format(cal.getTime(), "dd") + "号消耗" : i == 4 && j == 3 ? DateUtils.format(cal.getTime(), "dd") + "号消耗" : "");
                subSheet.add(sub);
            }
            shortcutItem.put("subSheet", subSheet);
            sheetShortcut.add(shortcutItem);
        }
        mouldStructure.put("sheetShortcut", sheetShortcut);
        LoginResult loginResult = new LoginResult();
        loginResult.setUserId(fsdUser.getId());
        loginResult.setJobNumber(fsdUser.getJobNumber());
        loginResult.setCardId(fsdUser.getCardId());
        loginResult.setName(fsdUser.getUserName());
        loginResult.setJob(fsdUser.getJob());
        loginResult.setRoles(roles);
        loginResult.setMouldStructure(mouldStructure);
        return loginResult;
    }

    @Override
    public Map<String, Object> getShortcutData(String stationCode) {
        JSONArray shortcut = JSONArray.parseArray(JSON.toJSONString(intelliAPIMapper.getShortcutData(stationCode)));
        Map<String, Object> res = new HashMap<>();
        Map subSheet = new HashMap();
        subSheet.put("subSheet1", shortcut.getJSONObject(0).getJSONArray("content").getJSONObject(0).getString("value"));//库存
        subSheet.put("subSheet2", shortcut.getJSONObject(0).getJSONArray("content").getJSONObject(1).getString("value"));//盘盈
        subSheet.put("subSheet3", shortcut.getJSONObject(0).getJSONArray("content").getJSONObject(2).getString("value"));//盘亏
        res.put("sheet1", subSheet);//库存统计

        subSheet = new HashMap();
        subSheet.put("subSheet1", shortcut.getJSONObject(1).getJSONArray("content").getJSONObject(0).getString("value"));//过效期
        subSheet.put("subSheet2", shortcut.getJSONObject(1).getJSONArray("content").getJSONObject(1).getString("value"));//近30天
        subSheet.put("subSheet3", shortcut.getJSONObject(1).getJSONArray("content").getJSONObject(2).getString("value"));//近60天
        res.put("sheet2", subSheet);//近效期统计

        subSheet = new HashMap();
        subSheet.put("subSheet1", shortcut.getJSONObject(2).getJSONArray("content").getJSONObject(0).getString("value"));//额定数量
        subSheet.put("subSheet2", shortcut.getJSONObject(2).getJSONArray("content").getJSONObject(1).getString("value"));
        subSheet.put("subSheet3", shortcut.getJSONObject(2).getJSONArray("content").getJSONObject(2).getString("value"));//差额数量
        res.put("sheet3", subSheet);//取出数量

        subSheet = new HashMap();
        subSheet.put("subSheet1", shortcut.getJSONObject(3).getJSONArray("content").getJSONObject(0).getString("value"));//当日消耗
        subSheet.put("subSheet2", shortcut.getJSONObject(3).getJSONArray("content").getJSONObject(1).getString("value"));//上日消耗
        subSheet.put("subSheet3", shortcut.getJSONObject(3).getJSONArray("content").getJSONObject(2).getString("value"));//前日消耗
        res.put("sheet4", subSheet);//消耗数量
        return res;
//        return intelliAPIMapper.getShortcutData(stationCode);
    }

    @Override
    public Object getScanResult(String stationCode, String business, List<SaveStockDTO> stockList) {
        logger.debug("getScanResult_start:"+business+"--"+stationCode);
        //获取上次扫描结果，对比本次扫描对库存的增减。
        List<String> stockRfids = fsdStockService.getStockByStationCode(stationCode).stream().map(FsdStock::getRfid).collect(Collectors.toList());
        // 获取扫描到的rfid集合
        List<String> actualRfids = stockList.stream().map(SaveStockDTO::getRfid).collect(Collectors.toList());
        UserPrincipal currentUser = UserUtils.currentUser();
        // 实时库存异步通知SPD
//        ExecutorService newSingleThreadPool = Executors.newSingleThreadExecutor();
//        newSingleThreadPool.execute(new Runnable() {
//            @Override
//            public void run() {
//                spdService.scanNotify(stationCode, actualRfids, "0.5", "fsd100", currentUser.getWorkNo());
//            }
//        });

        fsdtaskExecutor.execute(() -> spdService.scanNotify(stationCode, actualRfids, "0.5", "fsd100", currentUser.getWorkNo()));


        String changeTime = DateUtils.nowDate();
        //保存库存增加记录
        recordService.saveRecord(stationCode, changeTime, 1, new ArrayList<String>(CollectionUtils.subtract(actualRfids, stockRfids)));
        //保存库存减少记录
        recordService.saveRecord(stationCode, changeTime, 0, new ArrayList<String>(CollectionUtils.subtract(stockRfids, actualRfids)));

        //保存本次扫描的实际库存
        fsdStockService.saveStock(stationCode, stockList);
        //获取SPD库存视图中的理论库存
        List<StockResult> theoryStock = spdService.getStockByStationCode(stationCode);

        //获取理论库存的rfid集合
        List<String> theoryRfids = theoryStock.stream().map(StockResult::getRfid).collect(Collectors.toList());
//        Map<String, Object>  result= new HashMap<>();
        Map<String, Object> del = new HashMap<>();

        //扫描自动移库 报错不提示
        if(!business.equalsIgnoreCase("Transfer")) {
            FsdStation fsdStation = stationService.getOne(Wrappers.<FsdStation>query().eq("station_code", stationCode));
            if (fsdStation != null && fsdStation.getAutoTransfer() == true) {
                if (autoTrans(stationCode, actualRfids, theoryRfids, currentUser.getWorkNo())) {
                    //重新获取理论结果
                    theoryStock = spdService.getStockByStationCode(stationCode);
                    theoryRfids = theoryStock.stream().map(StockResult::getRfid).collect(Collectors.toList());
                }
            }
        }

        //所有智能柜站点集合
        List<String> StationCodes = stationService.list().stream().map(FsdStation::getStationCode).collect(Collectors.toList());
            switch (business) {
                case "Replenishment"://补货入库，返回新增的rfid
                    //arrayA扣除arrayB
                    Collection addRfids = CollectionUtils.subtract(actualRfids, theoryRfids);
                    del.put("difMat", spdService.getStockByListRfid(new ArrayList<String>(addRfids)).stream().filter((StockResult s) -> !StationCodes.contains(s.getStorageCode()) && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive()).collect(Collectors.toList()));
                    break;
                case "Transfer"://异柜移库，返回在别的智能柜中的rfid
                    Collection otherRfids = CollectionUtils.subtract(actualRfids, theoryRfids);
                del.put("difMat", spdService.getStockByListRfid(new ArrayList<String>(otherRfids)).stream().filter((StockResult s) -> StationCodes.contains(s.getStorageCode()) && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive()).collect(Collectors.toList()));
                break;
                case "Low_Consume"://定数包消耗返回缺失的低值rfid
                    Collection subRfids = CollectionUtils.subtract(theoryRfids, actualRfids);
                    del.put("difMat", theoryStock.stream().filter((StockResult s) -> subRfids.contains(s.getRfid()) && s.getType().equals("0") && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive()).collect(Collectors.toList()));
                 //  del.put("difMat", theoryStock.stream().filter((StockResult s) -> CollectionUtils.subtract(theoryRfids, actualRfids).contains(s.getRfid()) && s.getType().equals("0") && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive()).collect(Collectors.toList()));
                    break;
                case "Operation_Return"://手术还货(理论和实际都在本柜中，且为锁定状态)
                    Collection intersectionRfids = CollectionUtils.intersection(theoryRfids, actualRfids);
                      del.put("difMat", theoryStock.stream()
                              .filter((StockResult s) -> intersectionRfids.contains(s.getRfid()) && s.getLockQty() > 0 && s.getStockQty() > 0 && !s.getInactive())
                              .collect(Collectors.toList()));
                      //  del.put("difMat", theoryStock.stream()
                  //          .filter((StockResult s) -> CollectionUtils.intersection(theoryRfids, actualRfids).contains(s.getRfid()) && s.getLockQty() > 0 && s.getStockQty() > 0 && !s.getInactive())
                  //          .collect(Collectors.toList()));
                    break;
                case "Operation_Preparation":
                case "OperatingRoom_Preparation"://手术/手术间 备货返回缺失的高值rfid
                    Collection subRfids1 = CollectionUtils.subtract(theoryRfids, actualRfids);
                    del.put("difMat", theoryStock.stream()
                             .filter((StockResult s) ->subRfids1.contains(s.getRfid()) && s.getType().equals("1") && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive())
                            .collect(Collectors.toList()));
                    //del.put("difMat", theoryStock.stream()
                   //         .filter((StockResult s) -> CollectionUtils.subtract(theoryRfids, actualRfids).contains(s.getRfid()) && s.getType().equals("1") && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive())
                    //        .collect(Collectors.toList()));
                    break;
                case "Inventory":
                    List<Map<String, String>> contList = new ArrayList<>();
                    List<StockResult> StockResults = spdService.getStockByListRfid(new ArrayList<String>(CollectionUtils.disjunction(actualRfids, stockRfids)));//补集，差异部分
                    Map<String, String> contDel;
                    for (StockResult rec : StockResults) {
                        contDel = new HashMap<>();
                        contDel.put("msg", (stockRfids.contains(rec.getRfid()) ? "取出" : "放入") + rec.getMaterialName() + rec.getRfid());
                        contDel.put("time", changeTime);
                        contList.add(contDel);
                    }
                    logger.debug("getScanResult_end:Inventory " + business + "--" + stationCode);
                    return contList;
            }
        Collection intersection_unMat=CollectionUtils.intersection(actualRfids, theoryRfids);
        List<StockResult> un = theoryStock.stream()
                .filter((StockResult s) -> intersection_unMat.contains(s.getRfid()) && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive())
                .collect(Collectors.toList());
//        List<StockResult> un = theoryStock.stream()
//                .filter((StockResult s) -> CollectionUtils.intersection(actualRfids, theoryRfids).contains(s.getRfid()) && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive())
//                .collect(Collectors.toList());
        //返回理论和实际相符的rfid
        del.put("unMat", un);//2个数组取交集
//        result.add(del);
        //根据业务类型，比对库存差异，并返回耗材信息
        logger.debug("getScanResult_end:"+business+"--"+stationCode);
        return del;
    }

    @Override
    public List<Map<String, Object>> getMessageData(String stationCode) {
        List<Map<String, Object>> msgList = new ArrayList<>();
        Map<String, Object> del = new HashMap<>();
        List<Map<String, Object>> contList = new ArrayList<>();
        Map<String, Object> contDel;
        del.put("id", 10);
        del.put("title", "耗材相关");
        del.put("isNew", false);
        List<Map> records = recordService.getRecordByStationCode(stationCode);
        for (Map rec : records) {
            contDel = new HashMap<>();
            contDel.put("id", contList.size());
            contDel.put("msg", "" + rec.get("userName") + rec.get("type") + rec.get("MaterialName") + rec.get("rfid"));
            contDel.put("time", rec.get("changeTime"));
            contList.add(contDel);
        }
        del.put("content", contList);
        msgList.add(del);
        del = new HashMap<>();
        List<ReportResult> repExp = spdService.getReportDate(stationCode, "sheet2").get("subSheet1");
        del.put("id", repExp.size() > 0 ? 1 : 20);
        del.put("title", "警告消息");
        del.put("isNew", repExp.size() > 0);
        contList = new ArrayList<>();
        for (int i = 0; i < repExp.size(); i++) {
            contDel = new HashMap<>();
            contDel.put("id", i + 1);
            contDel.put("msg", repExp.get(i).getMaterialName() + "(" + repExp.get(i).getRfid() + "已过效期)");
            contDel.put("time", "EXP:" + repExp.get(i).getExp());
            contList.add(contDel);
        }
        del.put("content", contList);
        msgList.add(del);

        del = new HashMap<>();
        del.put("id", 30);
        del.put("title", "设备信息");
        del.put("isNew", false);
        contList = new ArrayList<>();
        contDel = new HashMap<>();
        contDel.put("id", 1);
        contDel.put("msg", "设备测试");
        contDel.put("time", DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        contList.add(contDel);
        del.put("content", contList);
        msgList.add(del);
        msgList.sort(Comparator.comparing(o -> o.get("id").toString()));
        return msgList;
    }

    @Override
    public Map<String, Object> getMouldOne(String business) {
        FsdRole role = fsdRoleService.getOne(new QueryWrapper<FsdRole>()
                .eq("role_key", business));
        if (role == null) throw new BusinessException("无效业务标识");
        Map<String, Object> item = new HashMap<>();

        Map<String, String> size = new HashMap<>();
        size.put("titleDiv", "10");//此处缺少后台配置
        size.put("listDiv", "85");
        size.put("bottomDiv", "5");
        item.put("size", size);

        Map<String, Object> titleCard = new HashMap<>();
        titleCard.put("title", role.getRoleName());
        List<List<Map<String, Object>>> contentList = new ArrayList<>();
        List<Map<String, Object>> contentItem = new ArrayList<>();
        Map<String, Object> cont = new HashMap<>();
        cont.put("label", "表单1");
        cont.put("value", "001");
        contentItem.add(cont);
        cont = new HashMap<>();
        cont.put("label", "表单2");
        cont.put("value", "0002");
        contentItem.add(cont);
        cont = new HashMap<>();
        cont.put("label", "表单3");
        cont.put("value", "00003");
        contentItem.add(cont);
        contentList.add(contentItem);

        contentItem = new ArrayList<>();
        cont = new HashMap<>();
        cont.put("label", "医师");
        cont.put("value", "付某某");
        contentItem.add(cont);
        contentList.add(contentItem);

        contentItem = new ArrayList<>();
        cont = new HashMap<>();
        cont.put("label", "护士");
        cont.put("value", "王某某");
        contentItem.add(cont);

        cont = new HashMap<>();
        cont.put("label", "护士");
        cont.put("value", "赵某某");
        contentItem.add(cont);
        contentList.add(contentItem);
//        titleCard.put("content", contentList);
        item.put("titleCard", titleCard);

        Map<String, Object> list = new HashMap<>();
        Map<String, Object> listitem = new HashMap<>();
        Map<String, Object> action = new HashMap<>();

        if (role.getRoleKey().equalsIgnoreCase("stock")) {//库存统计
            listitem.put("id", 1);
            listitem.put("title", "盘亏");
            action.put("isPicker", false);
            listitem.put("action", action);
            list.put("loss", listitem);

            listitem = new HashMap<>();
            action = new HashMap<>();
            listitem.put("id", 2);
            listitem.put("title", "盘盈");
            action.put("isPicker", false);
            listitem.put("action", action);
            list.put("surplus", listitem);

            listitem = new HashMap<>();
            action = new HashMap<>();
            listitem.put("id", 3);
            listitem.put("title", "库存");
            action.put("isPicker", false);
            listitem.put("action", action);
            list.put("stock", listitem);

//            listitem = new HashMap<>();
//            action = new HashMap<>();
//            listitem.put("id", 4);
//            listitem.put("title", "存取记录");
//            action.put("isPicker", false);
//            listitem.put("action", action);
//            list.put("log", listitem);
            item.put("list", list);
            return item;
        }

        listitem.put("id", 1);
        listitem.put("title", "预操作耗材");
        action.put("isPicker", true);
        listitem.put("action", action);
        list.put("difMat", listitem);

        listitem = new HashMap<>();
        action = new HashMap<>();
        listitem.put("id", 2);
        listitem.put("title", "库存耗材");
        action.put("isPicker", false);
        listitem.put("action", action);
        list.put("unMat", listitem);
        item.put("list", list);

        Map<String, Object> button = new HashMap<>();
        button.put("iconLogo", FsdConst.iconCheckSquare);
        button.put("iconName", "确认");
        item.put("button1", button);

        if (role.getRoleKey().equalsIgnoreCase("Operation_Preparation")) {
            List<String> select = new ArrayList<>();
            select.add("opNo");
            select.add("opRoom");
            select.add("doctor");
            item.put("listTwoSelect", select);

            Map<String, Object> listTwo = new HashMap<>();
            listTwo.put("title", "手术信息");
            Map<String, Object> label = new HashMap<>();
            Map<String, Object> labelItem = new HashMap<>();
            labelItem.put("name", "手术号");
            labelItem.put("span", 12);
            labelItem.put("isFilter", true);
            label.put("opNo", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "手术名");
            labelItem.put("span", 12);
            labelItem.put("isFilter", true);
            label.put("opName", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "手术间");
            labelItem.put("span", 12);
            labelItem.put("isFilter", true);
            label.put("opRoom", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "医师");
            labelItem.put("span", 12);
            labelItem.put("isFilter", true);
            label.put("doctor", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "病人");
            labelItem.put("span", 12);
            labelItem.put("isFilter", true);
            label.put("patient", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "手术时间");
            labelItem.put("span", 24);
            labelItem.put("isFilter", true);
            label.put("opTime", labelItem);
            listTwo.put("label", label);

            action = new HashMap<>();
            action.put("selectMode", "radio");
            listTwo.put("action", action);

            item.put("listTwo", listTwo);

            button = new HashMap<>();
            button.put("iconLogo", FsdConst.iconOutdent);
            button.put("iconName", "手术选择");
            item.put("button1", button);

            button = new HashMap<>();
            button.put("iconLogo", FsdConst.iconCheckSquare);
            button.put("iconName", "确认");
            item.put("button2", button);

            size = new HashMap<>();
            size.put("titleDiv", "15");
            size.put("listTwoSelectDiv", "15");
            size.put("listDiv", "65");
            size.put("bottomDiv", "5");
            item.put("size", size);
        }
        if (role.getRoleKey().equalsIgnoreCase("OperatingRoom_Preparation")) {
            List<String> select = new ArrayList<>();
            select.add("opRoomCode");
            select.add("opRoom");
            item.put("listTwoSelect", select);

            Map<String, Object> listTwo = new HashMap<>();
            listTwo.put("title", "手术间信息");
            Map<String, Object> label = new HashMap<>();
            Map<String, Object> labelItem = new HashMap<>();

            labelItem.put("name", "手术间编码");
            labelItem.put("span", 24);
            labelItem.put("isFilter", true);
            label.put("opRoomCode", labelItem);

            labelItem = new HashMap<>();
            labelItem.put("name", "手术间");
            labelItem.put("span", 24);
            labelItem.put("isFilter", true);
            label.put("opRoom", labelItem);

            listTwo.put("label", label);

            action = new HashMap<>();
            action.put("selectMode", "radio");
            listTwo.put("action", action);

            item.put("listTwo", listTwo);

            button = new HashMap<>();
            button.put("iconLogo", FsdConst.iconOutdent);
            button.put("iconName", "手术间选择");
            item.put("button1", button);

            button = new HashMap<>();
            button.put("iconLogo", FsdConst.iconCheckSquare);
            button.put("iconName", "确认");
            item.put("button2", button);

            size = new HashMap<>();
            size.put("titleDiv", "15");
            size.put("listTwoSelectDiv", "15");
            size.put("listDiv", "65");
            size.put("bottomDiv", "5");
            item.put("size", size);
        }
        if (role.getRoleKey().equalsIgnoreCase("Report")) {//报表模板
            item = new HashMap<>();
            List<Map<String, Object>> buttonList = new ArrayList<>();
            List<Object> allSheet = new ArrayList<>();
            for (int i = 1; i < 5; i++) {
                Map<String, Object> allSheetItem = new HashMap<>();
                button = new HashMap<>();
                button.put("iconLogo", FsdConst.iconClipboardList);
                button.put("iconName", i == 1 ? "库存统计" : i == 2 ? "近效期" : i == 3 ? "存取统计" : "消耗");
                button.put("sheetTab", "sheet" + i);
                buttonList.add(button);

                Map<String, String> sheetItem = new HashMap<>();
                sheetItem.put("tab", "sheet" + i);
                sheetItem.put("title", i == 1 ? "库存统计" : i == 2 ? "效期提醒" : i == 3 ? "存取统计" : "消耗明细");
                allSheetItem.put("sheet", sheetItem);
                List<Object> subSheet = new ArrayList<>();
                for (int j = 1; j < 4; j++) {
                    Calendar cal = Calendar.getInstance();
                    cal.add(Calendar.DATE, -j + 1);
                    Map<String, String> subSheetItem = new HashMap<>();
                    subSheetItem.put("tab", "subSheet" + j);
                    subSheetItem.put("title", i == 1 && j == 1 ? "盘亏" : i == 1 && j == 2 ? "盘盈" : i == 1 && j == 3 ? "库存" : i == 2 && j == 1 ? "过效期" : i == 2 && j == 2 ? "近30天" : i == 2 && j == 3 ? "近60天" : i == 3 && j == 1 ? DateUtils.format(new Date(), "dd") + "号存取" : i == 3 && j == 2 ? DateUtils.format(cal.getTime(), "dd") + "号存取" : i == 3 && j == 3 ? DateUtils.format(cal.getTime(), "dd") + "号存取" : i == 4 && j == 1 ? DateUtils.format(new Date(), "dd") + "号消耗" : i == 4 && j == 2 ? DateUtils.format(cal.getTime(), "dd") + "号消耗" : i == 4 && j == 3 ? DateUtils.format(cal.getTime(), "dd") + "号消耗" : "");
                    subSheet.add(subSheetItem);
                }
                allSheetItem.put("subSheet", subSheet);
                List<Object> matDesc = new ArrayList<>();
                Map<String, Object> matDescItem = new HashMap<>();
                if (i == 3) {
                    matDescItem.put("label", "用户");
                    Map<String, Object> search = new HashMap<>();
                    search.put("label", "用户或工号");
                    search.put("mode", "keyword");
                    search.put("addition", null);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
                    matDescItem = new HashMap<>();
                    matDescItem.put("label", "操作方式");
                    search = new HashMap<>();
                    search.put("label", "操作方式");
                    search.put("mode", "choice");
                    String[] choice = new String[]{"取出", "放入"};
                    search.put("addition", choice);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
//                    matDescItem = new HashMap<>();
//                    matDescItem.put("label", "操作时间");
//                    search = new HashMap<>();
//                    search.put("label", "操作时间");
//                    search.put("mode", "time");
//                    search.put("addition", null);
//                    matDescItem.put("search", search);
//                    matDesc.add(matDescItem);
                    matDescItem = new HashMap<>();
                    matDescItem.put("label", "耗材");
                    search = new HashMap<>();
                    search.put("label", "耗材");
                    search.put("mode", "keyword");
                    search.put("addition", null);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
                } else {
                    matDescItem.put("label", "品名");
                    Map<String, String> search = new HashMap<>();
                    search.put("label", "品名");
                    search.put("mode", "keyword");
                    search.put("addition", null);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
                    matDescItem = new HashMap<>();
                    matDescItem.put("label", "品规");
                    search = new HashMap<>();
                    search.put("label", "品规");
                    search.put("mode", "keyword");
                    search.put("addition", null);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
                    matDescItem = new HashMap<>();
                    matDescItem.put("label", "明细");
                    search = new HashMap<>();
                    search.put("label", "RFID");
                    search.put("mode", "keyword");
                    search.put("addition", null);
                    matDescItem.put("search", search);
                    matDesc.add(matDescItem);
                }
                allSheetItem.put("matDesc", matDesc);
                allSheet.add(allSheetItem);
            }
            item.put("button", buttonList);
            item.put("allSheet", allSheet);
            return item;
        }
        if (role.getRoleKey().equalsIgnoreCase("OutboundOrder") || role.getRoleKey().equalsIgnoreCase("Delivery")) { //出库单补货 / 耗材出库
            button = new HashMap<>();
            button.put("iconLogo", FsdConst.iconDollyflatbed);
            button.put("iconName", "开门");
            item.put("button2", button);
            list = new HashMap<>();
            listitem = new HashMap<>();
            action = new HashMap<>();
            listitem.put("id", 1);
            listitem.put("title", role.getRoleKey().equalsIgnoreCase("OutboundOrder") ? "配送单详情" : "出库单详情");
            action.put("isPicker", false);
            listitem.put("action", action);
            list.put("orderDet", listitem);
            item.put("list", list);
        }
        return item;
    }

    @Override
    public SPDResponseResult submit(String stationCode, String business, List<String> rfidList, String preparation) {
        UserPrincipal currentUser = UserUtils.currentUser();
        List<StockResult> stockResults = spdService.getStockByListRfid(rfidList);
        StorageResult storageResult = spdService.getStorageByStorageCode(stationCode);
        if (storageResult == null) {
            throw new BusinessException("站点编号在SPD中不存在！");
        }
        List<Map<String, String>> rfids = new ArrayList<>();
        SPDResponseResult spdResponseResult = new SPDResponseResult();
        for (StockResult stock : stockResults) {
            Map<String, String> sto = new HashMap<>();
            sto.put("rfid", stock.getRfid());
            sto.put("matrName", stock.getMaterialName());
            rfids.add(sto);
        }
        switch (business) {
            case "Replenishment":
            case "Transfer":
            case "Operation_Return"://入库确认
                String wiType = business.equals("Replenishment") ? "WI" : business.equals("Transfer") ? "WT" : "WB";
                RestResult res = spdService.wiNotify(stationCode, wiType, rfids, "0.5", "fsd100", currentUser.getWorkNo());
                spdResponseResult.setCode(res.getCode());
                spdResponseResult.setData(String.valueOf(res.getData()));
                spdResponseResult.setMsg(res.getMsg());
                if (res.getCode() == 0) {//入库成功，耗材放入记录操作人指定为入库人
                    List<String> rs=rfids.stream().map(r -> r.get("rfid")).collect(Collectors.toList());
                    recordService.update(Wrappers.<FsdRecord>update().set("user_id", currentUser.getId()).in("rfid", rs).eq("change_type", "1"));
                }
                break;
            case "Operation_Preparation"://手术备货
                spdResponseResult.setCode(1);
                spdResponseResult.setData("");
                spdResponseResult.setMsg("手术单号：" + preparation + ";暂不支持按手术单备货，请用手术间备货功能。");
                spdResponseResult.setSuccess(false);
                break;
            case "OperatingRoom_Preparation"://手术间备货
                JSONObject op = JSONObject.parseObject(spdService.woNotify(stationCode, "OP", preparation, rfids, "0.5", "fsd100", currentUser.getWorkNo()));
                spdResponseResult.setCode(op.getInteger("code"));
                spdResponseResult.setData(op.getString("data"));
                spdResponseResult.setMsg(op.getString("msg"));
                break;
            case "Low_Consume"://定数包消耗
                JSONObject consume = JSONObject.parseObject(spdService.consume(stationCode, rfids, "0.5", "fsd100", currentUser.getWorkNo()));
                spdResponseResult.setCode(consume.getInteger("code"));
                spdResponseResult.setData(consume.getString("data"));
                spdResponseResult.setMsg(consume.getString("msg"));
                break;
        }
        return spdResponseResult;
    }

    @Override
    public Object getStationCode() {
        List<FsdStation> fsdStations = stationService.list();
        if (fsdStations.size() == 0) throw new BusinessException("无可用站点，请先在后台配置站点！");
        List<Map<String, String>> data = new ArrayList<>();
        for (FsdStation station : fsdStations) {
            Map<String, String> stationInfo = new HashMap<>();
            stationInfo.put("stationCode", station.getStationCode());
            stationInfo.put("bindIp", station.getBindIp() == null ? "" : station.getBindIp());
            data.add(stationInfo);
        }
        return data;
    }

    @Override
    public Boolean submitStationCode(String chestStation) {
        stationService.update(Wrappers.<FsdStation>update().set("bind_ip", "").eq("bind_ip", WebUtils.getRequestIp()));
        FsdStation station = stationService.getOne(Wrappers.<FsdStation>update().eq("station_code", chestStation).last("limit 1"));
        station.setBindIp(WebUtils.getRequestIp());
        stationService.updateById(station);
        return true;
    }

    @Override
    public Boolean mouldTwoSubmit(String stationCode, String business, List<String> rfidList) {
        return null;
    }

    @Override
    public List<Map<String, Object>> getListTwo(String business) {

        List<Map<String, Object>> operas = new ArrayList<>();
        if (business.equals("Operation_Preparation")) {
            List<OperationResult> operations = spdService.getOperation();
            for (OperationResult operationResult : operations) {
                Map<String, Object> opera = new HashMap<>();
                Map<String, String> format = new HashMap<>();
                format.put("value", operationResult.getOpNo());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opNo", format);
                format = new HashMap<>();
                format.put("value", operationResult.getOpName());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opName", format);
                format = new HashMap<>();
                format.put("value", operationResult.getOpRoomName());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opRoom", format);
                format = new HashMap<>();
                format.put("value", operationResult.getDoctorName());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("doctor", format);
                format = new HashMap<>();
                format.put("value", operationResult.getPatientName());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("patient", format);
                format = new HashMap<>();
                format.put("value", operationResult.getOpTime());
//                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opTime", format);
                operas.add(opera);
            }

        }
        if (business.equals("OperatingRoom_Preparation")) {
            List<OperationRoomResult> operationRooms = spdService.getOperationRoom();
            for (OperationRoomResult operationRoom : operationRooms) {
                Map<String, Object> opera = new HashMap<>();
                Map<String, String> format = new HashMap<>();
                format.put("value", operationRoom.getOpRoomCode());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opRoomCode", format);
                format = new HashMap<>();
                format.put("value", operationRoom.getOpRoomName());
                format.put("py", PinYinUtils.getAlpha(format.get("value")));
                opera.put("opRoom", format);
                operas.add(opera);
            }
        }
        return operas;
    }

    @Override
    public Map<String, Object> getUserValidate(String jobNumber, String password) {
        Map<String, Object> map = new HashMap<>();
        FsdUser fsdUser = fsdUserService.getOne(Wrappers.<FsdUser>update().eq("job_number", jobNumber).eq("password", password).last("limit 1"));
        if (fsdUser != null)
            map.put("userId", fsdUser.id);
        return map;
    }

    @Override
    public List<Map<String, Object>> SyncFinger(String stationCode) {
        List<String> userIds = stationService.getUserIdByStationCode(stationCode);
        List<Map<String, Object>> fpList = fsdUserService.getFpTempByUserList(userIds);
        return fpList;
    }

    @Override
    public Boolean submitFingerTemplet(String id, String templet) {
        FsdFpTemplets fpTemplets = fsdFpTempletsService.getById(id);
        fpTemplets.setTemplet(templet);
        fpTemplets.setReCollection(false);
        fpTemplets.setVersion(fpTemplets.getVersion() + 1);
        fpTemplets.setDiscarded(false);
        return fsdFpTempletsService.updateById(fpTemplets);
    }

    @Override
    public Object getStockData(String stationCode) {
        logger.debug("getStockData_start:--"+stationCode);
        Map<String, Object> del = new HashMap<>();
        //获取上次扫描库存。
        List<String> stockRfids = fsdStockService.getStockByStationCode(stationCode).stream().map(FsdStock::getRfid).collect(Collectors.toList());

        //获取SPD库存视图中的理论库存
        List<StockResult> theoryStock = spdService.getStockByStationCode(stationCode);

        //获取理论库存的rfid集合
        List<String> theoryRfids = theoryStock.stream().map(StockResult::getRfid).collect(Collectors.toList());

        Collection subRfids = CollectionUtils.subtract(theoryRfids, stockRfids);
        List<StockResult> lossStock = theoryStock.stream()
                .filter((StockResult s) -> subRfids.contains(s.getRfid()) && s.getStockQty() > 0 && !s.getInactive())
                .collect(Collectors.toList());
//        List<StockResult> lossStock = theoryStock.stream()
//                .filter((StockResult s) -> CollectionUtils.subtract(theoryRfids, stockRfids).contains(s.getRfid()) && s.getStockQty() > 0 && !s.getInactive())
//                .collect(Collectors.toList());
        lossStock.forEach(stockResult -> {
            FsdRecord record = recordService.getOne(Wrappers.<FsdRecord>query().eq("rfid", stockResult.getRfid()).eq("change_type", 0).eq("station_code", stationCode).orderByDesc("change_time").last("limit 1"));
            List<Map<String, String>> desc = stockResult.getDesc();
            Map<String, String> item = new HashMap<>();
            item.put("label", "品名");
            if (record != null) {
                FsdUser fsdUser = fsdUserService.getById(record.getUserId());
                item.put("value", (stockResult.getLockQty() == 0 ? stockResult.getMaterialName() : stockResult.getDesc().get(0).get("value")) + "(" + fsdUser.getUserName() + "" + "于" + record.getChangeTime().substring(5) + "取出)");
                stockResult.setOrder(record.getChangeTime());
            } else {
                item.put("value", (stockResult.getLockQty() == 0 ? stockResult.getMaterialName() : stockResult.getDesc().get(0).get("value")) + "(无扫描记录)");
                stockResult.setOrder("");
            }
            desc.set(0, item);
            stockResult.setDesc(desc);
        });

        //缺失
        del.put("loss", lossStock.stream().sorted(Comparator.comparing(StockResult::getOrder).reversed()).collect(Collectors.toList()));
        //盘盈
        //theoryStock去掉库存中可用的耗材，对比出来才是全部多出来的标签
        Collection addRfids = CollectionUtils.subtract(stockRfids, theoryStock.stream().filter((StockResult s) -> s.getLockQty() == 0 && s.getStockQty() >0 && !s.getInactive()).map(StockResult::getRfid).collect(Collectors.toList()));
        List<StockResult> surplusStock = spdService.getStockByListRfid(new ArrayList<String>(addRfids));
        surplusStock.forEach(stockResult -> {
            if (stockResult.getStorageCode() != stationCode && !stockResult.getStorageCode().isEmpty() && stockResult.getMaterialName().equals(stockResult.getDesc().get(0).get("value"))) {
                List<Map<String, String>> desc = stockResult.getDesc();
                Map<String, String> item = new HashMap<>();
                item.put("label", "品名");
                item.put("value", stockResult.getMaterialName() + "(归属站点：" + stockResult.getStorageCode() + ")");
                desc.set(0, item);
                stockResult.setDesc(desc);
            }
        });
        del.put("surplus", surplusStock);

        Collection intersectionRfids = CollectionUtils.intersection(theoryRfids, stockRfids);
        del.put("stock", theoryStock.stream()
                .filter((StockResult s) -> intersectionRfids.contains(s.getRfid()) && s.getStockQty() > 0 && !s.getInactive())
                .collect(Collectors.toList()));
//        del.put("stock", theoryStock.stream()
//                .filter((StockResult s) -> CollectionUtils.intersection(theoryRfids, stockRfids).contains(s.getRfid()) && s.getStockQty() > 0 && !s.getInactive())
//                .collect(Collectors.toList()));

//        List<Map<String, Object>> contList = new ArrayList<>();
//        Map<String, Object> contDel;
//        List<Map> records = recordService.getRecordByStationCode(stationCode);
//        for (Map rec : records) {
//            contDel = new HashMap<>();
//            contDel.put("id", contList.size());
//            contDel.put("msg", "" + rec.get("userName") + rec.get("type") + rec.get("MaterialName"));
//            contDel.put("time", rec.get("changeTime"));
//            contList.add(contDel);
//        }
//        del.put("log", contList);
        logger.debug("getStockData_end:--"+stationCode);
        return del;
    }

    @Override
    public FsdStation getStationPara(String stationCode) {
        return stationService.getOne(Wrappers.<FsdStation>query().eq("station_code", stationCode));
    }

    @Override
    public List<Map<String, String>> getLastScanData(String stationCode) {
//        List<FsdRecord> records = recordService.list(Wrappers.<FsdRecord>query().eq("station_code",stationCode).eq("change_time",recordService.getOne(Wrappers.<FsdRecord>query().eq("station_code",stationCode).orderByDesc("change_time").last("limit 1")).getChangeTime()).orderByAsc("change_type"));
        List<Map> records = recordService.getLastScanRecordByStationCode(stationCode);
        if (records.size() == 0) return null;
        List<Map<String, String>> contList = new ArrayList<>();
        Map<String, String> contDel;
        for (Map rec : records) {
            contDel = new HashMap<>();
            contDel.put("msg", "" + rec.get("userName") + rec.get("type") + rec.get("MaterialName") + rec.get("rfid"));
            contDel.put("time", rec.get("changeTime").toString());
            contList.add(contDel);
        }
        return contList;
    }

    @Override
    public Object getSheetData(String stationCode, String sheetTab) {
        logger.debug("getSheetData_start:--"+stationCode);
        Map<String, Object> sheetData = new HashMap<>();
        Map<String, List<ReportResult>> report = spdService.getReportDate(stationCode, sheetTab);
        switch (sheetTab) {
            case "sheet1"://库存
            case "sheet2":
            case "sheet4":
                for (Map.Entry<String, List<ReportResult>> rep : report.entrySet()) {
                    List<Object> subSheet = new ArrayList();
                    for (ReportResult result : rep.getValue()) {
                        Map<String, Object> subSheetItem = new HashMap<>();
                        List<Map<String, Object>> desc = new ArrayList<>();
                        Map<String, Object> descItem = new HashMap<>();
                        subSheetItem.put("rfid", result.getRfid());
                        if (rep.getKey().equalsIgnoreCase("subSheet2")) { //sheetTab.equals("sheet1")&&(rep.getKey().equalsIgnoreCase("subSheet1")盘亏显示统计
                            descItem.put("value", result.getMaterialName() + result.getRfid() + result.getRemarks());
                            descItem.put("searchValue", PinYinUtils.getAlpha(descItem.get("value") + ""));
                            desc.add(descItem);
                        } else {
                            descItem.put("value", result.getMaterialName());
                            descItem.put("searchValue", PinYinUtils.getAlpha(result.getMaterialName()));
                            desc.add(descItem);
                        }
                        descItem = new HashMap<>();
                        descItem.put("value", result.getMaterialSpec());
                        descItem.put("searchValue", PinYinUtils.getAlpha(result.getMaterialSpec()));
                        desc.add(descItem);
                        descItem = new HashMap<>();
                        descItem.put("value", "RFID:" + result.getRfid() + ";Lot:" + result.getLot() + ";Exp:" + result.getExp() + (sheetTab.equalsIgnoreCase("sheet1") ? result.getRemarks() : ""));
                        descItem.put("searchValue", PinYinUtils.getAlpha(descItem.get("value") + ""));
                        desc.add(descItem);
                        subSheetItem.put("desc", desc);
                        subSheet.add(subSheetItem);
                    }
                    sheetData.put(rep.getKey(), subSheet);
                }
                break;
            case "sheet3"://存取记录
                for (Map.Entry<String, List<ReportResult>> rep : report.entrySet()) {
                    List<Object> subSheet = new ArrayList();
                    for (ReportResult result : rep.getValue()) {
                        Map<String, Object> subSheetItem = new HashMap<>();
                        List<Map<String, Object>> desc = new ArrayList<>();
                        Map<String, Object> descItem = new HashMap<>();
                        subSheetItem.put("rfid", result.getRfid());
                        descItem.put("value", result.getUserName() + "(" + result.getJobNumber() + ")");
                        descItem.put("searchValue", PinYinUtils.getAlpha(result.getUserName() + result.getJobNumber()));
                        desc.add(descItem);
                        descItem = new HashMap<>();
                        descItem.put("value", result.getOperationType());
                        descItem.put("searchValue", result.getOperationType());
                        desc.add(descItem);
//                        descItem = new HashMap<>();
//                        descItem.put("value",result.getOperationTime());
//                        descItem.put("searchValue",String.valueOf(DateUtils.parse(result.getOperationTime()).getTime()));
//                        desc.add(descItem);
                        descItem = new HashMap<>();
                        descItem.put("value", "RFID：" + result.getRfid() + ";品名：" + result.getMaterialName() + ";时间：" + result.getOperationTime());
                        descItem.put("searchValue", PinYinUtils.getAlpha(descItem.get("value") + ""));
                        desc.add(descItem);
                        subSheetItem.put("desc", desc);
                        subSheet.add(subSheetItem);
                    }
                    sheetData.put(rep.getKey(), subSheet);
                }
                break;
            default:
                break;
        }
        logger.debug("getSheetData_end:--"+stationCode);
        return sheetData;
    }

    /**
     * 定时消耗低值
     *
     * @return
     */
    public String timingConsume() {
        List<FsdStation> stations = stationService.list(Wrappers.<FsdStation>query().gt("auto_consume_ratio", 0));
        String result = "";
        for (FsdStation station : stations) {
//            List<StockResult> stockResults = spdService.getStockByListRfid(rfidList);
            //获取上次扫描库存。
            List<String> stockRfids = fsdStockService.getStockByStationCode(station.getStationCode()).stream().map(FsdStock::getRfid).collect(Collectors.toList());
            //获取SPD库存视图中的理论库存
            List<StockResult> theoryStock = spdService.getStockByStationCode(station.getStationCode());
            //获取理论库存的低耗rfid集合
            List<String> theoryRfids = theoryStock.stream().filter((StockResult s) ->s.getType().equals("0")).map(StockResult::getRfid).collect(Collectors.toList());
            List<StockResult> lossStock = theoryStock.stream()
                    .filter((StockResult s) -> CollectionUtils.subtract(theoryRfids, stockRfids).contains(s.getRfid()) && s.getType().equals("0") && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive())
                    .collect(Collectors.toList());
            if (lossStock.size() == 0 || theoryRfids.size() == 0)
                continue;
            if ((lossStock.size() / theoryRfids.size()) > (station.getAutoConsumeRatio() / 100) || (lossStock.size() / theoryRfids.size()) == 1)
                continue;
            List<Map<String, String>> rfids = new ArrayList<>();
            for (StockResult stock : lossStock) {
                Map<String, String> sto = new HashMap<>();
                sto.put("rfid", stock.getRfid());
                sto.put("matrName", stock.getMaterialName());
                rfids.add(sto);
            }
            JSONObject consume = JSONObject.parseObject(spdService.consume(station.getStationCode(), rfids, "0.5", "fsd100", "000000"));
            if (consume.getInteger("code") != 0)
                result += (result == "" ? "自动消耗失败，失败站点：" : ",") + station;
        }
        return result;
    }

    /**
     * 自动移库
     * @param stationCode
     * @param actualRfids
     * @param theoryRfids
     * @param WorkNo
     * @return
     */
    public Boolean autoTrans(String stationCode,List<String> actualRfids,List<String>theoryRfids,String WorkNo) {
        try {
            List<String> otherStationCodesInParent = jdbcTemplate.queryForList("select StorageCode From  view_fsd_warehouses  where ParentStorageCode=(select ParentStorageCode From view_fsd_warehouses where StorageCode='" + stationCode + "') and StorageCode !='" + stationCode + "'", String.class);
            if (otherStationCodesInParent.size() > 0) {
                Collection AutoTransferRfids = CollectionUtils.subtract(actualRfids, theoryRfids);
                List<StockResult> TransferRfids = spdService.getStockByListRfid(new ArrayList<String>(AutoTransferRfids)).stream().filter((StockResult s) -> otherStationCodesInParent.contains(s.getStorageCode()) && s.getLockQty() == 0 && s.getStockQty() > 0 && !s.getInactive()).collect(Collectors.toList());
                if (TransferRfids.size() > 0) {
                    List<Map<String, String>> rfids = new ArrayList<>();
                    for (StockResult stock : TransferRfids) {
                        Map<String, String> sto = new HashMap<>();
                        sto.put("rfid", stock.getRfid());
                        sto.put("matrName", stock.getMaterialName());
                        rfids.add(sto);
                    }
                    RestResult res = spdService.wiNotify(stationCode, "WT", rfids, "0.5", "fsd100", WorkNo);
                    if (res.getCode() == 0) {
                        return true;
                    }
                }
            }
        }catch (BusinessException e)
        {}
        catch (Exception e)
        {
            logger.error(e.toString());
        }
        return  false;
    }
}
